package com.zbkj.crmeb.system.service.impl;

import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSONArray;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.common.CheckAdminToken;
import com.common.CommonPage;
import com.common.PageParamRequest;
import com.constants.Constants;
import com.constants.SmsConstants;
import com.crmeb.core.exception.CrmebException;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.github.pagehelper.util.StringUtil;
import com.utils.CrmebUtil;
import com.utils.DateUtil;
import com.crmeb.core.utils.RedisUtil;
import com.zbkj.crmeb.agent.dao.AgentDao;
import com.zbkj.crmeb.agent.model.Agent;
import com.zbkj.crmeb.agent.service.AgentService;
import com.zbkj.crmeb.authorization.manager.TokenManager;
import com.zbkj.crmeb.authorization.model.TokenModel;
import com.zbkj.crmeb.chant.model.ChannelMerchant;
import com.zbkj.crmeb.chant.model.ChannelMerchantRenewal;
import com.zbkj.crmeb.chant.service.ChannelMerchantRenewalService;
import com.zbkj.crmeb.chant.service.IChannelMerchantService;
import com.zbkj.crmeb.enums.CurrencyEnum;
import com.zbkj.crmeb.enums.IdentityTypeEnum;
import com.zbkj.crmeb.enums.RoleEnum;
import com.zbkj.crmeb.sms.request.SendSmsVo;
import com.zbkj.crmeb.sms.service.SmsService;
import com.zbkj.crmeb.system.dao.SystemAdminDao;
import com.zbkj.crmeb.system.model.SystemAdmin;
import com.zbkj.crmeb.system.model.SystemRole;
import com.zbkj.crmeb.system.request.ForgetPwdRequest;
import com.zbkj.crmeb.system.request.SystemAdminAddRequest;
import com.zbkj.crmeb.system.request.SystemAdminRequest;
import com.zbkj.crmeb.system.request.SystemRoleSearchRequest;
import com.zbkj.crmeb.system.response.SystemAdminResponse;
import com.zbkj.crmeb.system.service.SystemAdminService;
import com.zbkj.crmeb.system.service.SystemRoleService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
* @author Mr.Zhang
* @Description SystemAdminServiceImpl 接口实现
* @since 2020-04-13
*/
@Service
public class SystemAdminServiceImpl extends ServiceImpl<SystemAdminDao, SystemAdmin> implements SystemAdminService {
    @Resource
    private SystemAdminDao dao;
    @Autowired
    private SystemRoleService systemRoleService;
    @Autowired
    private IChannelMerchantService channelMerchantService;
    @Resource
    private TokenManager tokenManager;
    @Autowired
    protected RedisUtil redisUtil;
    @Autowired
    CheckAdminToken checkAdminToken;
    @Resource
    private AgentDao agentDao;
    @Autowired
    private AgentService agentService;
    @Autowired
    private ChannelMerchantRenewalService channelMerchantRenewalService;
    @Autowired
    private RedisTemplate redisTemplate;
    @Autowired
    private SmsService smsService;

    @Value("${message.sendenable}")
    private String sendenable;

    @Override
    public PageInfo<SystemAdminResponse> getList(SystemAdminRequest request, PageParamRequest pageParamRequest){
        List<Integer> merIds = getAdminMerIds();
        if(CollectionUtils.isNotEmpty(merIds)) {
        	// 单独赋值供应商权限数据, 代码逻辑惨惨惨惨不忍睹
        	List<Integer> suppMerIds = channelMerchantService.list(Wrappers.<ChannelMerchant>lambdaQuery()
        			.eq(ChannelMerchant :: getChannelType, 3)
        			).stream().map(ChannelMerchant :: getId).collect(Collectors.toList());
        	merIds.addAll(suppMerIds);
        }
    	Page page = PageHelper.startPage(pageParamRequest.getPage(), pageParamRequest.getLimit());

        //带SystemAdminRequest类的多条件查询
        LambdaQueryWrapper<SystemAdmin> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        SystemAdmin systemAdmin = new SystemAdmin();
        BeanUtils.copyProperties(request,systemAdmin);
//        lambdaQueryWrapper.setEntity(systemAdmin);
        if(StringUtils.isNotBlank(systemAdmin.getAccount())){
            lambdaQueryWrapper.eq(SystemAdmin::getAccount, systemAdmin.getAccount());
        }
        if(null != systemAdmin.getId()){
            lambdaQueryWrapper.eq(SystemAdmin::getId, systemAdmin.getId());
        }
        lambdaQueryWrapper.eq(SystemAdmin::getIsDel, false);
        if(StringUtils.isNotBlank(systemAdmin.getLastIp())){
            lambdaQueryWrapper.eq(SystemAdmin::getLastIp, systemAdmin.getLastIp());
        }
        if(null != systemAdmin.getLevel()){
            lambdaQueryWrapper.eq(SystemAdmin::getLevel, systemAdmin.getLevel());
        }
        if(null != systemAdmin.getLoginCount()){
            lambdaQueryWrapper.eq(SystemAdmin::getLoginCount, systemAdmin.getLoginCount());
        }
        if(StringUtils.isNotBlank(systemAdmin.getRealName())){
            lambdaQueryWrapper.and(e->e.like(SystemAdmin::getRealName, systemAdmin.getRealName()).or().like(SystemAdmin::getAccount, systemAdmin.getRealName()));
        }
        if(StringUtils.isNotBlank(systemAdmin.getRoles())){
            lambdaQueryWrapper.eq(SystemAdmin::getRoles, systemAdmin.getRoles());
        }
        if(null != systemAdmin.getStatus()){
            lambdaQueryWrapper.eq(SystemAdmin::getStatus, systemAdmin.getStatus());
        }
        if(StringUtils.isNotBlank(systemAdmin.getMerId())){
            lambdaQueryWrapper.apply(StrUtil.format("SUBSTRING(mer_id, 2, LENGTH(mer_id)-2) in ({})", systemAdmin.getMerId()));
        }
        if(null != systemAdmin.getIdentityType()){
            lambdaQueryWrapper.eq(SystemAdmin::getIdentityType, systemAdmin.getIdentityType());
        }

        lambdaQueryWrapper.ne(SystemAdmin::getAccount, "admin");
        lambdaQueryWrapper.ne(SystemAdmin::getIdentityType, IdentityTypeEnum.SUPPER_ADMIN);

        if (Objects.nonNull(request.getAccountBindFlag())){
            lambdaQueryWrapper.eq(SystemAdmin::getAccountBindFlag, request.getAccountBindFlag());
        }
        if(CollectionUtils.isNotEmpty(merIds)) {
        	StringBuilder merIdsStr = new StringBuilder();
            merIdsStr.append("'',");
        	for(int merId : merIds) {
        		merIdsStr.append(merId);
        		merIdsStr.append(",");
        	}
        	lambdaQueryWrapper.last(StrUtil.format("AND SUBSTRING(mer_id, 2, LENGTH(mer_id)-2) in ({})", merIdsStr.substring(0, merIdsStr.length()-1)));
        } else {
        	lambdaQueryWrapper.orderByAsc(SystemAdmin::getId);
        }
        List<SystemAdmin> systemAdmins = dao.selectList(lambdaQueryWrapper);
        List<SystemAdminResponse> systemAdminResponses = new ArrayList<>();
        PageParamRequest pageRole = new PageParamRequest();
        pageRole.setLimit(999);
        List<SystemRole> roleList = systemRoleService.getList(new SystemRoleSearchRequest(), pageRole);
        // 所属商户
        List<ChannelMerchant> channelMerchants = channelMerchantService.list();
        Map<Integer, ChannelMerchant> channelMerchantMap = channelMerchants.stream().collect(Collectors.toMap(ChannelMerchant::getId, s -> s, (value1, value2) -> {
            return value1;
        }));

        for (SystemAdmin admin : systemAdmins) {
            SystemAdminResponse sar = new SystemAdminResponse();
            BeanUtils.copyProperties(admin, sar);
            sar.setLastTime(admin.getUpdateTime());
            if(StringUtils.isBlank(admin.getRoles())){
                continue;
            }
            List<Integer> roleIds = CrmebUtil.stringToArrayInt(admin.getRoles());
            List<String> roleNames = new ArrayList<>();
            for (Integer roleId : roleIds) {
                List<SystemRole> hasRoles = roleList.stream().filter(e -> e.getId().equals(roleId)).collect(Collectors.toList());
                if(hasRoles.size()> 0){
                    roleNames.add(hasRoles.stream().map(SystemRole::getRoleName).collect(Collectors.joining(",")));
                }
            }
            sar.setRoleNames(StringUtils.join(roleNames,","));
            String replace = admin.getMerId().replace("[", "").replace("]", "");
            if (StringUtils.isNotBlank(replace)) {
                List<Integer> merIds1 = CrmebUtil.stringToArrayInt(replace);
                StringBuilder sb = new StringBuilder();
                for (Integer merId : merIds1) {
                    ChannelMerchant channelMerchant = channelMerchantMap.get(merId);
                    if(null != channelMerchant) {
                        sb.append(channelMerchant.getChannelName());
                        sb.append(",");
                    }
                }
                sb.deleteCharAt(sb.lastIndexOf(","));
                sar.setMerName(sb.toString());
            }
            systemAdminResponses.add(sar);
        }
        return CommonPage.copyPageInfo(page, systemAdminResponses);
    }

    @Override
    public SystemAdminResponse login(SystemAdminRequest request, String ip, String identification) {
    	String account = request.getAccount();
        LambdaQueryWrapper<SystemAdmin> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(SystemAdmin::getAccount, account);
        SystemAdmin systemAdmin = dao.selectOne(lambdaQueryWrapper);
        String encryptPassword = CrmebUtil.encryptPassword(request.getPwd(), account);
       
        if(null == systemAdmin){
            throw new CrmebException("账号或者密码不正确");
        }
        if(!systemAdmin.getStatus()){
            throw new CrmebException("用户已经被禁用");
        }
        if(systemAdmin.getIsDel()){
            throw new CrmebException("用户已经被删除");
        }
        if(!systemAdmin.getPwd().equals(encryptPassword)){
        	// 用户尝试登陆次数
            Integer loginTime = (Integer) redisUtil.get(account);
        	Long expire = redisUtil.getExpire(account);
            if (Objects.isNull(loginTime)){
                redisUtil.set(account, 1, 5L, TimeUnit.MINUTES);
            // 5分钟内，失败次数达到5次
            } else if(loginTime >= 5) {
            	throw new CrmebException(StrUtil.format("失败次数过多，请{}秒后重试！", expire));
            } else {
                redisUtil.set(account, loginTime + 1, expire, TimeUnit.SECONDS);
            }
        	
            throw new CrmebException("账号或者密码不正确");
        }
        TokenModel tokenModel = tokenManager.createToken(systemAdmin.getAccount(), systemAdmin.getId().toString(), systemAdmin.getMerId(), TokenModel.TOKEN_REDIS);
        SystemAdminResponse systemAdminResponse = new SystemAdminResponse();
        systemAdminResponse.setToken(tokenModel.getToken());
        systemAdmin.setUpdateTime(DateUtil.nowDateTime());
        BeanUtils.copyProperties(systemAdmin, systemAdminResponse);

        // 校验商户剩余使用时间
		/*if(systemAdmin.getIdentityType() == 2){
		    Integer merId = (Integer) JSONArray.parseArray(systemAdmin.getMerId()).get(0);
		    ChannelMerchantRenewal merchantRenewal = channelMerchantRenewalService.getOne(Wrappers.<ChannelMerchantRenewal>lambdaQuery().eq(ChannelMerchantRenewal::getMerId,merId).orderByDesc(ChannelMerchantRenewal::getId).last("LIMIT 1"));
		    if(merchantRenewal == null || merchantRenewal.getExpirationTime().before(new Date())){
		        throw new CrmebException("您的后台使用期限已到，请联系平台进行续费");
		    }
		}*/

        // 处理账号身份类型
        if (0 == systemAdmin.getIdentityType()) {
            List<Integer> merIdList = JSONArray.parseArray(systemAdmin.getMerId()).toJavaList(Integer.class);
            systemAdminResponse.setIdentityType(merIdList.size() == 1 ? IdentityTypeEnum.MERCHANT.getCode() : IdentityTypeEnum.PLATFORM.getCode());
            systemAdmin.setIdentityType(systemAdminResponse.getIdentityType());
        }

        //更新最后登录信息
        systemAdmin.setLoginCount(systemAdmin.getLoginCount() + 1);
        systemAdmin.setLastIp(ip);
        if(StringUtils.isBlank(identification) || !"APP".equalsIgnoreCase(identification)) {
            systemAdmin.setNowToken(tokenModel.getToken());
        }
        updateById(systemAdmin);
        systemAdminResponse.setNewFlag("松松大哥");

        return systemAdminResponse;
    }

    @Override
    public Boolean logout(String token) throws Exception {
        tokenManager.deleteToken(token, TokenModel.TOKEN_REDIS);
        redisUtil.remove(StrUtil.format(Constants.ADMIN_TOKEN_MER_KEY, token));
        return true;
    }

    /**
     * 管理员详情
     * @param request
     * @return
     * @throws Exception
     */
    @Override
    public SystemAdminResponse getInfo(SystemAdminRequest request) throws Exception {
        QueryWrapper queryWrapper = new QueryWrapper();
//        queryWrapper.eq("account", request.getAccount());
//        queryWrapper.eq("account", request.getAccount());
        queryWrapper.eq("id", request.getId());
        SystemAdmin systemAdmin = dao.selectOne(queryWrapper);

        if(null == systemAdmin || systemAdmin.getId() < 0){
            return null;
        }
        SystemAdminResponse systemAdminResponse = new SystemAdminResponse();
        BeanUtils.copyProperties(systemAdmin, systemAdminResponse);

        List<Integer> merIdList = handleMerIds(systemAdmin);
        if(CollectionUtils.isNotEmpty(merIdList)) {
        	ChannelMerchant channelMerchant = channelMerchantService.getById(merIdList.get(0));
        	if (Objects.nonNull(channelMerchant)) {
                ChannelMerchantRenewal merchantRenewal = channelMerchantRenewalService.getOne(Wrappers.<ChannelMerchantRenewal>lambdaQuery().eq(ChannelMerchantRenewal::getMerId,channelMerchant.getId()).orderByDesc(ChannelMerchantRenewal::getId).last("LIMIT 1"));
                if(merchantRenewal != null){
                    systemAdminResponse.setExpirationTime(merchantRenewal.getExpirationTime());
                }
                systemAdminResponse.setMerName(channelMerchant.getChannelName());
                systemAdminResponse.setAppletType(channelMerchant.getAppletType());
                systemAdminResponse.setSecondHand(channelMerchant.getSecondHand());
                if(StringUtils.isNotBlank(channelMerchant.getCurrency())){
                    systemAdminResponse.setCurrencyEnum(CurrencyEnum.valueOf(channelMerchant.getCurrency()));
                }
                systemAdminResponse.setAutoPush(channelMerchant.getAutoPush());
            }
        }

        return systemAdminResponse;
    }

    /**
     * 新增管理员
     * @param systemAdminAddRequest
     * @return
     */
    @Override
    public SystemAdminResponse saveAdmin(SystemAdminAddRequest systemAdminAddRequest) {
        try {
            // 管理员名称唯一校验
            Integer result = checkAccount(systemAdminAddRequest.getAccount());
            if (result > 0) {
                throw new CrmebException("管理员已存在");
            }

            SystemAdmin systemAdmin = new SystemAdmin();
            BeanUtils.copyProperties(systemAdminAddRequest, systemAdmin);

            // 执行新增管理员操作
            String pwd = CrmebUtil.encryptPassword(systemAdmin.getPwd(), systemAdmin.getAccount());
            systemAdmin.setPwd(pwd); // 设置为加密后的密码
            SystemAdminResponse systemAdminResponse = new SystemAdminResponse();
            BeanUtils.copyProperties(systemAdminAddRequest, systemAdminResponse);
            if (Objects.isNull(systemAdminAddRequest.getCreatorId())){
                systemAdmin.setCreatorId(getAdminId());
            }
            if (Objects.isNull(systemAdmin.getPhone())){
                throw new CrmebException("手机号不能为空");
            }
            if(dao.insert(systemAdmin) <= 0){
                throw new CrmebException("新增管理员失败");
            }
            systemAdminResponse.setId(systemAdmin.getId());
            return systemAdminResponse;

        }catch (Exception e){
            throw new CrmebException("新增管理员异常 " + e.getMessage());
        }

    }

    private Integer checkAccount(String account) {
        LambdaQueryWrapper<SystemAdmin> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(SystemAdmin::getAccount, account);
        return dao.selectCount(lambdaQueryWrapper);

    }

    @Override
    public SystemAdminResponse updateAdmin(SystemAdminRequest systemAdminRequest,String originalPwd) throws Exception {
        SystemAdminResponse systemAdminResponseExsit = getInfo(systemAdminRequest);
        if(null == systemAdminResponseExsit){
            throw new CrmebException("管理员不存在");
        }
        if (!StringUtils.isEmpty(originalPwd)){
            SystemAdmin request = dao.selectById(systemAdminRequest.getId());
            String oldPwd = CrmebUtil.decryptPassowrd(request.getPwd(), request.getAccount());
            if (!oldPwd.equals(originalPwd)){
                throw new CrmebException("原始密码错误");
            }
            if (oldPwd.equals(systemAdminRequest.getPwd())){
                throw new CrmebException("新密码不能和原始密码一致");
            }
        }
        SystemAdmin systemAdmin = new SystemAdmin();
        BeanUtils.copyProperties(systemAdminRequest, systemAdmin);
        if(null != systemAdminRequest.getPwd()){
            String pwd = CrmebUtil.encryptPassword(systemAdminRequest.getPwd(), systemAdminRequest.getAccount());
            systemAdmin.setPwd(pwd);
        }

        if(dao.updateById(systemAdmin) > 0){
            SystemAdminResponse systemAdminResponse = new SystemAdminResponse();
            BeanUtils.copyProperties(systemAdmin, systemAdminResponse);
            return systemAdminResponse;

        }
        throw new CrmebException("更新管理员异常");
    }

    @Override
    public SystemAdminResponse getInfoByToken(String token) throws Exception{
        Boolean tokenExsit = tokenManager.checkToken(token, TokenModel.TOKEN_REDIS);
        if(!tokenExsit){
            throw new CrmebException("请重新登录");
        }
        TokenModel tokenModel = tokenManager.getToken(token, TokenModel.TOKEN_REDIS);
        SystemAdminRequest systemAdminRequest = new SystemAdminRequest();
//        systemAdminRequest.setAccount(tokenModel.getUserNo());
        systemAdminRequest.setId(tokenModel.getUserId());
        return getInfo(systemAdminRequest);
    }

    /**
     * 获取当前用户id
     * @author Mr.Zhang
     * @since 2020-04-28
     * @return Integer
     */
    @Override
    public Integer getAdminId() {
        RequestAttributes requestAttributes = RequestContextHolder.currentRequestAttributes();
        HttpServletRequest request = ((ServletRequestAttributes)requestAttributes).getRequest();
        String token = checkAdminToken.getTokenFormRequest(request);
        if(StringUtil.isEmpty(token)){
            throw new CrmebException("token已失效,请重新登录!");
        }
        Object id = redisUtil.get(TokenModel.TOKEN_REDIS+token);
        if(null == id) {
            throw new CrmebException("token已失效,请重新登录!");
        }
        return (Integer.parseInt(id.toString()));
    }

    /**
     * 获取当前用户信息
     * @author Mr.Zhang
     * @since 2020-04-28
     * @return SystemAdmin
     */
    @Override
    public SystemAdmin getInfo() {
        return getInfo(getAdminId());
    }

    /**
     * 获取当前用户默认商户
     * @author Mr.Zhang
     * @since 2020-04-28
     * @return SystemAdmin
     */
    @Override
    public Integer getAdminMerId() {
        RequestAttributes requestAttributes = RequestContextHolder.currentRequestAttributes();
        HttpServletRequest request = ((ServletRequestAttributes)requestAttributes).getRequest();

        String token =request.getParameter(Constants.HEADER_AUTHORIZATION_KEY);
        if(StringUtil.isEmpty(token)){
        	token = request.getHeader(Constants.HEADER_AUTHORIZATION_KEY);
        }
        Object merId = redisUtil.get(StrUtil.format(Constants.ADMIN_TOKEN_MER_KEY, token));
        // 前端用户
        if(null == merId) {
            merId = request.getHeader(Constants.HEADER_MERCHANT_ID);
        }
        return null == merId ? null : Integer.parseInt(merId.toString());
	}

    /**
     * 获取当前用户所属商户
     * @author Mr.Zhang
     * @since 2020-04-28
     * @return SystemAdmin
     */
    @Override
    public List<Integer> getAdminMerIds() {
    	SystemAdmin admin = getInfo(getAdminId());
    	return JSONArray.parseArray(admin.getMerId()).toJavaList(Integer.class);
    }

    /**
     * 获取用户信息
     * @author Mr.Zhang
     * @since 2020-04-28
     * @return SystemAdmin
     */
    @Override
    public SystemAdmin getInfo(Integer adminId) {
        // 处理merId 所有
        SystemAdmin systemAdmin = getById(adminId);
        List<Integer> merIds = handleMerIds(systemAdmin);
        systemAdmin.setMerId(Arrays.toString(merIds.toArray(new Integer[0])));
        return systemAdmin;
    }

    @Override
    public List<Integer> getAdminAgentMerIds() {
//        SystemAdmin admin = getInfo(getAdminId());
//        return handleMerIds(admin);
        return getAdminMerIds();
    }

    /**
     * 处理账号所属商户id
     *
     * @param admin
     * @return
     */
    private List<Integer> handleMerIds(SystemAdmin admin) {
        // 指定商户
        List<Integer> merIds = JSONArray.parseArray(admin.getMerId()).toJavaList(Integer.class);
        if (CollectionUtils.isNotEmpty(merIds)) {
            return merIds;
        }
        // 二级
        if (IdentityTypeEnum.AGENCY_TWO.getCode().equals(admin.getIdentityType())) {
            List<Integer> secondAgentIds = JSONArray.parseArray(admin.getTwoAgentIds()).toJavaList(Integer.class);
            return getTwoLevelAgentMerIds(Collections.singletonList(secondAgentIds.get(0)));

        } else if (IdentityTypeEnum.AGENCY_ONE.getCode().equals(admin.getIdentityType())) {
            // 一级
            List<Integer> firstAgentId = JSONArray.parseArray(admin.getOneAgentIds()).toJavaList(Integer.class);
            // 1.1二级为空
            if (StringUtils.isBlank(admin.getTwoAgentIds())) {
                return getTwoLevelAgentMerIds(firstAgentId);
            }
            List<Integer> twoLevelAgentIds = JSONArray.parseArray(admin.getTwoAgentIds()).toJavaList(Integer.class);
            // 1.2二级全部
            if (CollectionUtils.isEmpty(twoLevelAgentIds)) {
                // 1.21二级
                List<Agent> agents = agentDao.selectList(Wrappers.<Agent>lambdaQuery()
                        .in(Agent::getParentId, firstAgentId)
                        .eq(Agent::getIsDel, 0));
                twoLevelAgentIds = agents.stream().map(Agent::getId).collect(Collectors.toList());
            }
            // 1.2 二级加一级
            twoLevelAgentIds.addAll(firstAgentId);
            return getTwoLevelAgentMerIds(twoLevelAgentIds);

        }
        // todo 除一二级服务商和超级管理员，其余账号都有指定商户
        return new ArrayList<>();
    }


    /**
     * 获取所有服务商户ids去重
     *
     * @param agentIds 服务商ids
     * @return
     */
    private List<Integer> getTwoLevelAgentMerIds(List<Integer> agentIds) {
        LambdaQueryWrapper<ChannelMerchant> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.select(ChannelMerchant::getId);
        lambdaQueryWrapper.in(CollectionUtils.isNotEmpty(agentIds), ChannelMerchant::getAgentId, agentIds)
                .eq(ChannelMerchant::getIsDel, 0);
        List<ChannelMerchant> channelMerchants = channelMerchantService.list(lambdaQueryWrapper);

        return channelMerchants.stream().map(ChannelMerchant::getId).distinct().collect(Collectors.toList());
    }


    /**
     * 获取当前账户服务商id
     *
     * @return
     */
    @Override
    public Integer getAdminAgentId() {
        SystemAdmin admin = getInfo(getAdminId());
        if (IdentityTypeEnum.AGENCY_ONE.getCode().equals(admin.getIdentityType())) {
            // 一级服务商：只可以选择1个一级代理（一级必填
            return JSONArray.parseArray(admin.getOneAgentIds()).toJavaList(Integer.class).get(0);
        }
        if (IdentityTypeEnum.AGENCY_TWO.getCode().equals(admin.getIdentityType())) {
            // 二级级服务商：只可以选择1个二级代理（必填
            return JSONArray.parseArray(admin.getTwoAgentIds()).toJavaList(Integer.class).get(0);
        }
        return null;
    }

    /**
     * 校验参数
     *
     * @param request
     */
    @Override
    public void validatedSystemAdmin(SystemAdminAddRequest request) {
        // 一级代理
        if (IdentityTypeEnum.AGENCY_ONE.getCode().equals(request.getIdentityType())) {
            if (StringUtils.isBlank(request.getOneAgentIds())) {
                throw new CrmebException("请选择一级服务商");
            }
            if (StringUtils.isBlank(request.getMerId())) {
                throw new CrmebException("请选择商户");
            }
            List<Integer> agentIds = JSONArray.parseArray(request.getOneAgentIds()).toJavaList(Integer.class);
            if (StringUtils.isBlank(request.getTwoAgentIds())) {
                request.setTwoAgentIds("");
            } else {
                List<Integer> secondAgentIds = JSONArray.parseArray(request.getTwoAgentIds()).toJavaList(Integer.class);
                if (CollectionUtils.isEmpty(secondAgentIds)) {
                    List<Agent> agents = agentDao.selectList(Wrappers.<Agent>lambdaQuery()
                            .in(Agent::getParentId, agentIds)
                            .eq(Agent::getIsDel, 0));
                    secondAgentIds = agents.stream().map(Agent::getId).collect(Collectors.toList());
                }
                agentIds.addAll(secondAgentIds);
            }
            // 校验服务商是否有所属商户
            List<Integer> merIds = getTwoLevelAgentMerIds(agentIds);
            if (CollectionUtils.isEmpty(merIds)) {
                throw new CrmebException("当前服务商下无商户");
            }

        } else if (IdentityTypeEnum.AGENCY_TWO.getCode().equals(request.getIdentityType())) {
            if (StringUtils.isBlank(request.getTwoAgentIds())) {
                throw new CrmebException("请选择二级服务商");
            }
            if (StringUtils.isBlank(request.getMerId())) {
                throw new CrmebException("请选择商户");
            }
            Integer agentId = JSONArray.parseArray(request.getTwoAgentIds()).toJavaList(Integer.class).get(0);
            Agent agent = agentService.getById(agentId);
            if (Objects.isNull(agent) || agent.getParentId() == 0) {
                throw new CrmebException("当前二级服务商不存在");
            }
            // 校验服务商是否有所属商户
            List<Integer> merIds = getTwoLevelAgentMerIds(Collections.singletonList(agentId));
            if (CollectionUtils.isEmpty(merIds)) {
                throw new CrmebException("当前服务商下无商户");
            }
            request.setOneAgentIds(Collections.singleton(agent.getParentId()).toString());
        } else if (IdentityTypeEnum.PLATFORM.getCode().equals(request.getIdentityType())) {
            // 必须选择商户
           /* if (StringUtils.isBlank(request.getMerId()) || Constants.SystemAdminAll.equals(request.getMerId())) {
                throw new CrmebException("请选择商户");
            }*/
            if (StringUtils.isBlank(request.getMerId())) {
                throw new CrmebException("请选择商户");
            }
            if (StringUtils.isBlank(request.getOneAgentIds())) {
                request.setOneAgentIds("");
            }
            if (StringUtils.isBlank(request.getTwoAgentIds())) {
                request.setTwoAgentIds("");
            }

        } else if (IdentityTypeEnum.MERCHANT.getCode().equals(request.getIdentityType())) {
            if (StringUtils.isBlank(request.getMerId())) {
                throw new CrmebException("请选择商户");
            }
           /* if (StringUtils.isBlank(request.getMerId()) || Constants.SystemAdminAll.equals(request.getMerId())) {
                throw new CrmebException("请选择商户");
            }*/
        }

    }

    @Override
    public void validatedSystemAdmin(SystemAdminRequest systemAdminRequest) {
        SystemAdminAddRequest request = new SystemAdminAddRequest();
        BeanUtils.copyProperties(systemAdminRequest, request);
        validatedSystemAdmin(request);
    }

    @Override
    public Boolean accountBinding(Integer merchantId, Integer supplierId) {
        SystemAdmin merAdmin = checkAdminAccount(merchantId,IdentityTypeEnum.MERCHANT);
        SystemAdmin supAdmin = checkAdminAccount(supplierId,IdentityTypeEnum.SUPPLER);

        SystemAdmin systemAdminMer = new SystemAdmin();
        systemAdminMer.setId(merAdmin.getId());
        systemAdminMer.setAccountBindFlag(true);
        systemAdminMer.setAccountBindId(supAdmin.getId());

        SystemAdmin systemAdminSup = new SystemAdmin();
        systemAdminSup.setId(supAdmin.getId());
        systemAdminSup.setAccountBindFlag(true);
        systemAdminSup.setAccountBindId(merAdmin.getId());

        List<SystemAdmin> systemAdminList = new ArrayList<>();
        systemAdminList.add(systemAdminMer);
        systemAdminList.add(systemAdminSup);
        return this.updateBatchById(systemAdminList);
    }

    @Override
    public Boolean accountUnbinding(Integer id) throws Exception {
        SystemAdmin systemAdmin = this.getById(id);
        if (Objects.isNull(systemAdmin)){
            throw new CrmebException("请检查账号[" + id + "]是否存在");
        }
        if (!systemAdmin.getAccountBindFlag()){
            throw new CrmebException("账号不存在绑定关系");
        }
        SystemAdmin systemAdmin1 = this.getById(systemAdmin.getAccountBindId());
        List<Integer> integerList = new ArrayList<>();
        integerList.add(systemAdmin.getId());
        integerList.add(systemAdmin.getAccountBindId());
        //解除账号绑定并对账号进行登出

        logout(systemAdmin.getNowToken());
        logout(systemAdmin1.getNowToken());
        return this.update(Wrappers.lambdaUpdate(SystemAdmin.class)
                .set(SystemAdmin::getAccountBindFlag,false)
                .set(SystemAdmin::getAccountBindId,null)
                .in(SystemAdmin::getId,integerList));
    }

    @Override
    public SystemAdminResponse passwordFreeLogin(String token, String ip) throws Exception {
        //获取登录用户信息
        SystemAdminResponse systemAdminResponse = getInfoByToken(token);
        if (Objects.isNull(systemAdminResponse)){
            return null;
        }
        if (!systemAdminResponse.getAccountBindFlag()){
            throw new CrmebException("用户没有绑定关系");
        }
        SystemAdmin systemAdmin = this.getById(systemAdminResponse.getAccountBindId());
        if(null == systemAdmin){
            throw new CrmebException("绑定账号不存在");
        }
        if(!systemAdmin.getStatus()){
            throw new CrmebException("绑定账号已经被禁用");
        }

        if(systemAdmin.getIsDel()){
            throw new CrmebException("绑定账号已经被删除");
        }
        TokenModel tokenModel = tokenManager.createToken(systemAdmin.getAccount(), systemAdmin.getId().toString(), systemAdmin.getMerId(), TokenModel.TOKEN_REDIS);
        SystemAdminResponse adminResponse = new SystemAdminResponse();
        adminResponse.setToken(tokenModel.getToken());
        systemAdmin.setUpdateTime(DateUtil.nowDateTime());
        BeanUtils.copyProperties(systemAdmin, adminResponse);

        // 处理账号身份类型
        if (0 == systemAdmin.getIdentityType()) {
            List<Integer> merIdList = JSONArray.parseArray(systemAdmin.getMerId()).toJavaList(Integer.class);
            adminResponse.setIdentityType(merIdList.size() == 1 ? IdentityTypeEnum.MERCHANT.getCode() : IdentityTypeEnum.PLATFORM.getCode());
            systemAdmin.setIdentityType(adminResponse.getIdentityType());
        }

        //更新最后登录信息
        systemAdmin.setLoginCount(systemAdmin.getLoginCount() + 1);
        systemAdmin.setLastIp(ip);
        systemAdmin.setNowToken(tokenModel.getToken());
        updateById(systemAdmin);
        return adminResponse;
    }

    /**
     * 功能描述: 修改密码
     * @Param: [request]
     * @Return: java.lang.Boolean
     * @Author: wangzh
     * @Date: 2023/4/21 16:33
     */
    @Override
    public Boolean forgotPwd(ForgetPwdRequest request) {
        validateCode(request);

        SystemAdmin systemAdmin = getOne(Wrappers.<SystemAdmin>lambdaQuery().eq(SystemAdmin::getAccount, request.getAccount()));
        if (Objects.isNull(systemAdmin)) {
            throw new CrmebException("账号不存在");
        } else if (systemAdmin.getIsDel()) {
            throw new CrmebException("账号已被删除");
        } else if (!systemAdmin.getStatus()) {
            throw new CrmebException("账号被禁用");
        } else if (!StringUtils.equals(systemAdmin.getPhone(), request.getPhone())) {
            throw new CrmebException("手机号不正确");
        }

        // 加密密码
        String password = CrmebUtil.encryptPassword(request.getPwd(), request.getAccount());
        return this.update(Wrappers.<SystemAdmin>lambdaUpdate().eq(SystemAdmin::getAccount, request.getAccount())
                .eq(SystemAdmin::getPhone, request.getPhone())
                .set(SystemAdmin::getPwd, password));
    }

    /**
     * 功能描述: 忘记密码发送验证码
     * @Param: [phone]
     * @Return: java.lang.Boolean
     * @Author: wangzh
     * @Date: 2023/4/21 15:25
     */
    @Override
    public Boolean sendCode(String phone, Integer template) {
        SendSmsVo sendSmsVo = new SendSmsVo();
        sendSmsVo.setMobiles(phone);
        sendSmsVo.setMobile(phone);
        sendSmsVo.setSendEnable(sendenable);
        sendSmsVo.setTemplate(template);
        sendSmsVo.setCaptcha(CrmebUtil.randomCount(111111, 999999) + "");
        return smsService.sendMessage(sendSmsVo);
    }

    @Override
    public SystemAdminResponse registerAccount(ForgetPwdRequest request) {
        validateCode(request);

        SystemAdminAddRequest systemAdminAddRequest = new SystemAdminAddRequest();
        systemAdminAddRequest.setAccount(request.getPhone());
        systemAdminAddRequest.setPwd(request.getPwd());
        systemAdminAddRequest.setRealName(request.getAccount());
        systemAdminAddRequest.setRoles(RoleEnum.getRoleByMsg("体验版").getRole());
        systemAdminAddRequest.setLevel(1);
        systemAdminAddRequest.setStatus(true);
        systemAdminAddRequest.setIdentityType(2);
        systemAdminAddRequest.setPhone(request.getPhone());
        systemAdminAddRequest.setCreatorId(1);

        return saveAdmin(systemAdminAddRequest);
    }

    /**
     * 校验账号类型
     * @param id
     * @param identityTypeEnum
     * @return com.zbkj.crmeb.system.model.SystemAdmin
     */
    public SystemAdmin checkAdminAccount(Integer id, IdentityTypeEnum identityTypeEnum){
        SystemAdmin systemAdmin = this.getById(id);
        if (Objects.isNull(systemAdmin)){
            throw new CrmebException("请检查账号[" + id + "]是否存在");
        }
        if (!Objects.equals(identityTypeEnum.getCode(),systemAdmin.getIdentityType())){
            throw new CrmebException("请检查账号[" + id + "]是否为" + identityTypeEnum.getMsg() + "账号");
        }
        if(!systemAdmin.getStatus()){
            throw new CrmebException("用户已经被禁用");
        }
        if(systemAdmin.getIsDel()){
            throw new CrmebException("用户已经被删除");
        }
        if(systemAdmin.getAccountBindFlag()){
            throw new CrmebException("用户已经被绑定");
        }
        return systemAdmin;
    }

    /**
     * 功能描述: 验证手机验证码
     * @Param: [request]
     * @Return: void
     * @Author: wangzh
     * @Date: 2023/4/23 15:11
     */
    private void validateCode(ForgetPwdRequest request) {
        Object validateCode = redisUtil.get(SmsConstants.SMS_VALIDATE_PHONE + request.getPhone());
        if(validateCode == null){
            throw new CrmebException("验证码已过期");
        }

        if(!validateCode.toString().equals(request.getCode())){
            throw new CrmebException("验证码错误");
        }
        redisUtil.remove(SmsConstants.SMS_VALIDATE_PHONE + request.getPhone());
    }

}

